package com.czy.tank.game;

import com.czy.tank.common.Dir;
import com.czy.tank.common.Group;
import com.czy.tank.config.PropertyMgr;
import com.czy.tank.config.ResourceMgr;
import com.czy.tank.pattern.strategy.fire.DefaultFireStrategy;
import com.czy.tank.pattern.strategy.fire.FireStrategy;
import com.czy.tank.pattern.strategy.fire.FourFireStrategy;

import java.awt.*;
import java.util.Random;

/********************************************************************
 * @brief 坦克类
 * @version 0.1
 * @date 2022年08月30日 22:22
 * @author changziyang
 ********************************************************************/
public class Tank {
    public int x,y;
    /*坦克方向*/
    public Dir dir;
    //public TankFrame tankFrame;
    /*定义坦克速度 10*/
    private static final int SPEED = PropertyMgr.getInstance().getInt("tankSpeed");
    /*坦克是否移动状态 false:静止*/
    private boolean moving = false;
    /*坦克存活状态，碰撞子弹时死亡*/
    private boolean living = true;
    /*定义随机数，地方坦克，随机方向发射子弹*/
    private Random random = new Random();
    /*定义展示图片,闪烁切换坦克图片,true展示图片1 false展示图片2*/
    private volatile boolean flag = true;
    /*敌我双方分组*/
    private Group group;
    /*定义坦克当前宽高*/
    public int WIDTH = ResourceMgr.badTank1D.getWidth();
    public int HEIGHT = ResourceMgr.badTank1D.getHeight();
    /*当前子弹的矩形边界*/
    public Rectangle rectangle = new Rectangle();
    /*定义当前子弹开火模式*/
    private FireStrategy fireStrategy;

    public Tank(int x, int y, Dir dir,TankFrame tankFrame,Group group) {
        this.x = x;
        this.y = y;
        this.dir = dir;
        //this.tankFrame = tankFrame;
        this.group = group;
       if (group == Group.BAD){
            //敌方坦克 自动移动
            this.moving = true;
            this.fireStrategy = DefaultFireStrategy.getInstance();
        }else{
           this.fireStrategy = FourFireStrategy.getInstance();
       }
    }
    public void paint(Graphics g){
        //画个矩形 模拟坦克
        /*Color c = g.getColor();
        g.setColor(Color.YELLOW);
        g.fillRect(x, y, 50, 50);
        g.setColor(c);*/
        if (!living){
            TankFrame.getInstance().badTanks.remove(this);
        }
        /*根据方向画出坦克*/
        if (flag){
            switch (dir){
                case LEFT:
                    g.drawImage(this.group == Group.GOOD ? ResourceMgr.goodTank1L : ResourceMgr.badTank1L,x,y,null);
                    WIDTH = ResourceMgr.goodTank1L.getWidth();
                    HEIGHT = ResourceMgr.goodTank1L.getHeight();
                    break;
                case UP:
                    g.drawImage(this.group == Group.GOOD ? ResourceMgr.goodTank1U : ResourceMgr.badTank1U,x,y,null);
                    WIDTH = ResourceMgr.goodTank1U.getWidth();
                    HEIGHT = ResourceMgr.goodTank1U.getHeight();
                    break;
                case RIGHT:
                    g.drawImage(this.group == Group.GOOD ? ResourceMgr.goodTank1R : ResourceMgr.badTank1R,x,y,null);
                    WIDTH = ResourceMgr.goodTank1R.getWidth();
                    HEIGHT = ResourceMgr.goodTank1R.getHeight();
                    break;
                case DOWN:
                    g.drawImage(this.group == Group.GOOD ? ResourceMgr.goodTank1D : ResourceMgr.badTank1D,x,y,null);
                    WIDTH = ResourceMgr.goodTank1D.getWidth();
                    HEIGHT = ResourceMgr.goodTank1D.getHeight();
                    break;
                default:
                    break;
            }
        }else {
            switch (dir){
                case LEFT:
                    g.drawImage(this.group == Group.GOOD ? ResourceMgr.goodTank2L : ResourceMgr.badTank2L,x,y,null);
                    WIDTH = ResourceMgr.badTank1L.getWidth();
                    HEIGHT = ResourceMgr.badTank1L.getHeight();
                    break;
                case UP:
                    g.drawImage(this.group == Group.GOOD ? ResourceMgr.goodTank2U : ResourceMgr.badTank2U,x,y,null);
                    WIDTH = ResourceMgr.badTank1U.getWidth();
                    HEIGHT = ResourceMgr.badTank1U.getHeight();
                    break;
                case RIGHT:
                    g.drawImage(this.group == Group.GOOD ? ResourceMgr.goodTank2R : ResourceMgr.badTank2R,x,y,null);
                    WIDTH = ResourceMgr.badTank1R.getWidth();
                    HEIGHT = ResourceMgr.badTank1R.getHeight();
                    break;
                case DOWN:
                    g.drawImage(this.group == Group.GOOD ? ResourceMgr.goodTank2D : ResourceMgr.badTank2D,x,y,null);
                    WIDTH = ResourceMgr.badTank1D.getWidth();
                    HEIGHT = ResourceMgr.badTank1D.getHeight();
                    break;
                default:
                    break;
            }
        }
        /*改变边界的宽高*/
        this.rectangle.width = this.WIDTH;
        this.rectangle.height = this.HEIGHT;
        move();

    }

    /*************************************************
    * 方法描述:坦克移动方法
    * @param
    * @return void
    * @author create: 人员:【changziyang】类型:【新增方法】日期:【2022/8/30 22:35】
    * @author modify:
    **************************************************/
    private void move() {
        if(!living) {
            return;
        }
        if (!moving){
            return;
        }
        switch (dir){
            case LEFT:
                x -= SPEED;
                break;
            case UP:
                y -= SPEED;
                break;
            case RIGHT:
                x += SPEED;
                break;
            case DOWN:
                y += SPEED;
                break;
            default:
                break;
        }
        //改变边界的xy
        this.rectangle.x = this.x;
        this.rectangle.y = this.y;
        /*敌方坦克移动时自动攻击*/
        if (this.group == Group.BAD && random.nextInt(100) > 95){
            this.fire();
        }
        /*敌方坦克移动时随机改变方向移动*/
        if(this.group == Group.BAD && random.nextInt(100) > 96){
            randomDir();
        }
        boundsCheck();
    }

    /*************************************************
    * 方法描述:坦克边界检测，不能跑出窗口
    * @param
    * @return void
    * @author create: 人员:【changziyang】类型:【新增方法】日期:【2022/9/1 15:59】
    * @author modify:
    **************************************************/
    private void boundsCheck() {
        if (this.x < 2){
            x = 2;
        }
        if (this.y < 28) {
            y = 28;
        }
        if (this.x > TankFrame.GAME_WIDTH- this.WIDTH -2) {
            x = TankFrame.GAME_WIDTH - this.WIDTH -2;
        }
        if (this.y > TankFrame.GAME_HEIGHT - this.HEIGHT -2 ) {
            y = TankFrame.GAME_HEIGHT -this.HEIGHT -2;
        }
    }

    /*************************************************
    * 方法描述:坦克随机改变方向移动
    * @param
    * @return void
    * @author create: 人员:【changziyang】类型:【新增方法】日期:【2022/9/1 14:46】
    * @author modify:
    **************************************************/
    private void randomDir() {
        //枚举类型四个方向 对应四个数字，随机一个数据改变方向
        this.dir = Dir.values()[random.nextInt(4)];
    }

    /*************************************************
    * 方法描述:坦克死亡
    * @param
    * @return void
    * @author create: 人员:【changziyang】类型:【新增方法】日期:【2022/9/1 14:40】
    * @author modify:
    **************************************************/
    public void die(){
        this.living = false;
    }
    /*************************************************
     * 方法描述:坦克发射子弹
     * @param
     * @return void
     * @author create: 人员:【changziyang】类型:【新增方法】日期:【2022/8/30 22:51】
     * @author modify:
     **************************************************/
    public void fire() {
        fireStrategy.fire(this);
    }

    public Dir getDir() {
        return dir;
    }

    public void setDir(Dir dir) {
        this.dir = dir;
    }

    public boolean isMoving() {
        return moving;
    }

    public void setMoving(boolean moving) {
        this.moving = moving;
    }
    public boolean isLiving() {
        return living;
    }

    public void setLiving(boolean living) {
        this.living = living;
    }

    public int getX() {
        return x;
    }

    public void setX(int x) {
        this.x = x;
    }

    public int getY() {
        return y;
    }

    public void setY(int y) {
        this.y = y;
    }

    public Group getGroup() {
        return group;
    }

    public void setGroup(Group group) {
        this.group = group;
    }

    public boolean isFlag() {
        return flag;
    }

    public void setFlag(boolean flag) {
        this.flag = flag;
    }
}
